package com.ruoyi.web.runner;

import cn.hutool.crypto.symmetric.AES;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.web.constant.WalletConstant;
import com.ruoyi.web.domain.Currency;
import com.ruoyi.web.domain.RechargeRecord;
import com.ruoyi.web.enums.CommonDictEnum;
import com.ruoyi.web.enums.UserEnums;
import com.ruoyi.web.service.ICurrencyService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.tron.trident.core.ApiWrapper;
import org.tron.trident.proto.Chain;
import org.tron.trident.proto.Response;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.utils.Convert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 用户充值时发送手续费
 */
@Component
@AllArgsConstructor
public class SendServiceCharge {

	private final ICurrencyService currencyService;

	private final static BigDecimal ETH_FEE = new BigDecimal("0.01");

	private final static BigDecimal TRON_FEE = BigDecimal.TEN;

	/**
	 * 波场发送手续费
	 * @param record 充值记录信息
	 */
	public void tronFee(RechargeRecord record){
		try {
			List<Currency> currencies = currencyService.selectCurrencyList(new Currency() {{
				setName(WalletConstant.USDT);
				setPublicChain(UserEnums.Chain.TRX.getValue());
				setState(CommonDictEnum.Status.NORMAL.getValue());
			}});
			Currency currency = currencies.size() > 0 ? currencies.get(0) : null;
			if (currency == null) {
				return;
			}
			// 解密私钥
			String decryptStr;
			try {
				AES aes = new AES(WalletConstant.AES_KEY);
				decryptStr = aes.decryptStr(currency.getServiceChargePrivateKey());
			} catch (Exception e) {
				decryptStr = currency.getServiceChargePrivateKey();
			}
			// 主网
			ApiWrapper wrapper = ApiWrapper.ofMainnet(decryptStr, currency.getApiKey());
			// 测试网
//			ApiWrapper wrapper = ApiWrapper.ofNile(decryptStr);

			// 手续费账户 TRX 余额
			Response.Account account = wrapper.getAccount(currency.getServiceChargeAddress());
			BigDecimal decimal = BigDecimal.valueOf(account.getBalance()).divide(new BigDecimal("1000000"),6, RoundingMode.DOWN);

			// 充值用户 TRX 余额
			Response.Account userAccount = wrapper.getAccount(record.getArrivalAddress());
			BigDecimal userDecimal = BigDecimal.valueOf(userAccount.getBalance()).divide(new BigDecimal("1000000"),6, RoundingMode.DOWN);

			// 如果用户trx余额不足10 且 手续费账户有足够trx 则给用户拨款
			if (userDecimal.compareTo(TRON_FEE) < 0 && decimal.compareTo(TRON_FEE.subtract(userDecimal)) >= 0) {
				BigDecimal subtract = TRON_FEE.subtract(userDecimal).multiply(new BigDecimal("1000000"));

				Response.TransactionExtention transfer = wrapper.transfer(
						currency.getServiceChargeAddress(),
						record.getArrivalAddress(),
						subtract.longValue()
				);
				Chain.Transaction transaction = wrapper.signTransaction(transfer);
				wrapper.broadcastTransaction(transaction);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * 以太坊发送手续费
	 * @param record 充值记录信息
	 */
	public void ethFee(RechargeRecord record,String chain) {
		try {
			// 获取UNT 币种
			List<Currency> currencies = currencyService.selectCurrencyList(new Currency() {{
				setName(WalletConstant.USDT);
				setPublicChain(chain);
				setState(CommonDictEnum.Status.NORMAL.getValue());
			}});
			Currency currency = currencies.size() > 0 ? currencies.get(0) : null;
			if (currency == null) {
				return;
			}
			// 查询手续费usc余额
			Web3j web3j = Web3j.build(new HttpService(currency.getNodeAddress() + currency.getApiKey()));
			EthGetBalance send = web3j.ethGetBalance(currency.getServiceChargeAddress(), DefaultBlockParameterName.LATEST).send();
			BigDecimal decimal = Convert.fromWei(new BigDecimal(send.getBalance()), Convert.Unit.ETHER);

			// 查询用户usc余额
			EthGetBalance balance = web3j.ethGetBalance(record.getArrivalAddress(), DefaultBlockParameterName.LATEST).send();
			BigDecimal userDecimal = Convert.fromWei(new BigDecimal(balance.getBalance()), Convert.Unit.ETHER);
			// 如果用户usc余额不足0.01 且 手续费账户有足够usc 则给用户拨款
			if (userDecimal.compareTo(ETH_FEE) < 0 && decimal.compareTo(ETH_FEE) >= 0) {
				BigDecimal subtract = ETH_FEE.subtract(userDecimal);
				String str;
				try {
					AES aes = new AES(WalletConstant.AES_KEY);
					str = aes.decryptStr(currency.getServiceChargePrivateKey());
				} catch (Exception e) {
					str = currency.getServiceChargePrivateKey();
				}
				Credentials credentials = Credentials.create(str);
				TransactionReceipt receipt = Transfer.sendFunds(
						web3j,
						credentials,
						record.getArrivalAddress(),
						subtract,
						Convert.Unit.ETHER).send();
				receipt.getBlockHash();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
